home *** CD-ROM | disk | FTP | other *** search
/ MacFormat 1995 March / macformat-022.iso / Reader's Corner / Reader's Contibutions / David Hart / Source Code / Mystic Rose 2.0 / Mystic Rose.c < prev    next >
Encoding:
C/C++ Source or Header  |  1994-09-22  |  5.0 KB  |  224 lines  |  [TEXT/KAHL]

  1. /*
  2.     Filename    Mystic Rose.c
  3.     Copyright © 1994 David Hart. All rights reserved.
  4.     Author        David Hart
  5.     Description    Mystic Rose module for After Dark
  6.     
  7.     Version      Date        Comments
  8.     2.00    18/04/94    Original version for After Dark version 2.0
  9. */
  10.  
  11. #include <QuickDraw.h>
  12. #include <Memory.h>
  13. #include <OSUtils.h>
  14. #include <math.h>
  15. #include "GraphicsModule_Types.h"
  16.  
  17. /* Function prototypes */
  18. void    Wait(int ticks);
  19.  
  20. /* Color Table */
  21. long    Colors[] = {
  22.     /*    blackColor,    */
  23.         whiteColor,
  24.         redColor,
  25.         greenColor,
  26.         blueColor,
  27.         cyanColor,
  28.         magentaColor,
  29.         yellowColor };
  30.  
  31. /* Specific graphics module data structures */
  32. typedef struct MyStorage
  33.     {
  34.     int    numPoints;
  35.     int    length;
  36.     int    point1;
  37.     int    point2;
  38.     } MyStorage, *MyStoragePtr, **MyStorageHandle;
  39.  
  40. /*
  41.     DoInitialize is the first function called from After Dark.
  42.     Memory for the structure is allocated and the variables are initialized.
  43.     The allocated memory is assigned to "storage"
  44.     and the function returns "noErr" if there are no problems.
  45. */
  46. OSErr    DoInitialize(Handle *storage, RgnHandle blankRgn, GMParamBlockPtr params)
  47.     {
  48.     MyStorageHandle myStorage;
  49.     
  50.     /* allocate handle to my storage */
  51.     myStorage = (MyStorageHandle)NewHandle(sizeof(MyStorage));
  52.     
  53.     if (!myStorage)
  54.         return MemError();
  55.     
  56.     MoveHHi(myStorage);
  57.     HLock(myStorage);                    /* Lock it down */
  58.     
  59.     *storage = (Handle)myStorage;        /* Assign myStorage to passed handle */
  60.     
  61.     (**myStorage).numPoints = params->controlValues[0] / 3 + 4;
  62.     (**myStorage).length = 1;
  63.     (**myStorage).point1 = 0;
  64.     (**myStorage).point2 = 1;
  65.     HUnlock(myStorage);
  66.     return noErr;
  67.     }
  68.  
  69. /*  
  70.     DoBlank is the next function called.
  71.     It is used to simply blank the screen.
  72. */ 
  73. OSErr    DoBlank(Handle storage, RgnHandle blankRgn, GMParamBlockPtr params)
  74.     {
  75.     FillRgn(blankRgn, params->qdGlobalsCopy->qdBlack);
  76.     return noErr;
  77.     }
  78.  
  79. /*
  80.     DoDrawFrame does almost all of the work.
  81. */
  82. OSErr    DoDrawFrame(Handle storage, RgnHandle blankRgn, GMParamBlockPtr params)
  83.     {
  84.     OSErr err = noErr;
  85.     MyStoragePtr myStorage;                /* to hold dereferenced storage handle */
  86.     int    minSize;
  87.     int    maxSize;
  88.     int    x1, y1;
  89.     int    x2, y2;
  90.     int    radius;
  91.     double    theta;
  92.  
  93.     int    width;
  94.     int    height;
  95.     int size;
  96.     int    color;
  97.     int    monitor;
  98.     int    xmid;
  99.     int    ymid;
  100.     Rect    rect;
  101.  
  102.     /* Lock our storage down so we can dereference it once for faster access */
  103.     MoveHHi(storage);
  104.     HLock(storage);
  105.     myStorage = (MyStoragePtr)*storage;
  106.     
  107.     /* Get params */
  108.     minSize = params->controlValues[0] / 3 + 4;
  109.     maxSize = params->controlValues[1] / 3 + 4;
  110.     
  111.     /* Color */
  112.     switch (params->controlValues[3])
  113.         {
  114.         case 8:    /* rainbow */
  115.             color = myStorage->point1 % 7 + 1;
  116.             break;
  117.         case 9:    /* cycle */
  118.             color = myStorage->numPoints % 7 + 1;
  119.             break;
  120.         default:
  121.             color = params->controlValues[3] - 1;
  122.             break;
  123.         }
  124.     
  125.     /* For each monitor */
  126.     for (monitor = 0; monitor < params->monitors->monitorCount; monitor++)
  127.         {
  128.         rect = params->monitors->monitorList[monitor].bounds;
  129.         xmid = (rect.left + rect.right) / 2;
  130.         ymid = (rect.top + rect.bottom) / 2;
  131.         width = rect.right - rect.left;
  132.         height = rect.bottom - rect.top;
  133.         size = width < height ? width : height;
  134.         radius = size / 2;
  135.         
  136.         theta = 2 * 3.14159 / myStorage->numPoints;
  137.         
  138.         /* Calculate coords of point1 */
  139.         x1 = cos(theta * myStorage->point1) * radius;
  140.         y1 = sin(theta * myStorage->point1) * radius;
  141.  
  142.         /* Calculate coords of point2 */
  143.         myStorage->point2 = myStorage->point1 + myStorage->length;
  144.         x2 = cos(theta * myStorage->point2) * radius;
  145.         y2 = sin(theta * myStorage->point2) * radius;
  146.         
  147.         /* Draw line from point1 to point2 */
  148.         ForeColor(Colors[color]);
  149.         MoveTo(x1 + xmid, y1 + ymid);
  150.         LineTo(x2 + xmid, y2 + ymid);
  151.         }
  152.     
  153.     /* Next point1 */
  154.     myStorage->point1++;
  155.     if (myStorage->point1 >= myStorage->numPoints)
  156.         {
  157.         /* All points done, reset and try longer line */
  158.         myStorage->point1 = 0;
  159.         
  160.         /* Increase line length */
  161.         myStorage->length++;
  162.         if (myStorage->length >= myStorage->numPoints/2+1)
  163.             {
  164.             /* All lines done, reset and try more points */
  165.             myStorage->length = 1;
  166.             
  167.             /* Increase number of points */
  168.             myStorage->numPoints++;
  169.             if (myStorage->numPoints > maxSize)
  170.                 {
  171.                 /* Max number of points done, reset to min */
  172.                 myStorage->numPoints = minSize;
  173.                 }
  174.                 
  175.             /* Delay before blanking screen */
  176.             Wait(120);
  177.             ForeColor(blackColor);
  178.             FillRgn(blankRgn, params->qdGlobalsCopy->qdBlack);
  179.             }
  180.         }
  181.     
  182.     HUnlock(storage);
  183.     return noErr;
  184.     }
  185.  
  186. /*
  187.     DoClose is called when the user quits the screen saver.
  188.     The memory is deallocated and the function returns "MemError"
  189.     which will tell After Dark if there was a problem
  190. */
  191. OSErr    DoClose(Handle storage, RgnHandle blankRgn, GMParamBlockPtr params)
  192.     {
  193.     MyStorageHandle myStorage = (MyStorageHandle)storage;
  194.         
  195.     /* Deallocate our storage */
  196.     if (myStorage)
  197.         {
  198.         MoveHHi(myStorage);
  199.         HLock(myStorage);
  200.         DisposHandle(storage);
  201.         }
  202.     
  203.     /* check for memory errors */
  204.     return MemError();
  205.     }
  206.  
  207. /*
  208.     DoSetUp is called if the user clicks on a button in the Control Panel.
  209. */
  210. OSErr    DoSetUp(RgnHandle blankRgn, short message, GMParamBlockPtr params)
  211.     {
  212.     return noErr;
  213.     }
  214.  
  215. /*
  216.     Wait delays ticks TickCount
  217. */
  218. void    Wait(int ticks)
  219.     {
  220.     long    tickCount = TickCount();
  221.     
  222.     while (TickCount() < tickCount + ticks);
  223.     }
  224.